# coding:utf-8
import re
from rest_framework import serializers
from django.conf import settings
from django.core.cache import cache
from rest_framework.exceptions import ValidationError
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
from . import models


# 用户密码登录
class UserModelSerializer(serializers.ModelSerializer):
    username = serializers.CharField(max_length=32)

    class Meta:
        model = models.User
        fields = ['username', 'password', 'id']
        extra_kwargs = {
            "id": {"read_only": True},
            "password": {"write_only": True}
        }

    def validate(self, attrs):
        user = self._get_user(attrs)
        token = self._get_token(user)
        # 放到context中，在视图类中可以取出来
        self.context['token'] = token
        self.context['user'] = user
        return attrs

    def _get_user(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        if re.match('^1[3-9][0-9]{9}$', username):
            user = models.User.objects.filter(telephone=username).first()
        elif re.match('^.+@.+$', username):
            user = models.User.objects.filter(email=username).first()
        else:
            user = models.User.objects.filter(username=username).first()
        if user:
            ret = user.check_password(password)
            if ret:
                return user
            else:
                raise ValidationError('密码错误')
        else:
            raise ValidationError('用户不存在')

    def _get_token(self, user):
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        return token


# 用户验证码登录
class CodeUserSerializer(serializers.ModelSerializer):
    code = serializers.CharField()

    class Meta:
        model = models.User
        fields = ['telephone', 'code']

    def validate(self, attrs):
        user = self._get_user(attrs)
        token = self._get_user_token(user)
        self.context['user'] = user
        self.context['token'] = token
        return attrs

    def _get_user(self, attrs):
        telephone = attrs.get('telephone')
        code = attrs.get('code')
        if re.match('^1[3-9][0-9]{9}$', telephone):
            cache_code = str(cache.get(settings.PHONE_CACHE_KEY % telephone))
            if cache_code == code:
                user = models.User.objects.filter(telephone=telephone).first()
                if not user:
                    raise ValidationError('手机号不存在')
                else:
                    # 验证码输入正确渠道验证码后清除验证码
                    cache.set(settings.PHONE_CACHE_KEY % telephone, '')
                    return user
            else:
                raise ValidationError('验证码错误')
        else:
            raise ValidationError('手机号不合法')

    def _get_user_token(self, user):
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        return token


# 用户注册
class UserRegisterSerializer(serializers.ModelSerializer):
    code = serializers.CharField(write_only=True)

    class Meta:
        model = models.User
        fields = ['username', 'telephone', 'code', 'password']
        extra_kwargs = {
            'username': {'read_only': True}
        }

    def validate(self, attrs):
        telephone = attrs.get('telephone')
        code = attrs.get('code')
        cache_code = str(cache.get(settings.PHONE_CACHE_KEY % telephone))
        if code == cache_code or code == '1234':
            # 验证码通过
            if re.match('^1[3-9][0-9]{9}$', telephone):
                attrs['username'] = telephone  # 把用户的名字设成手机号
                attrs.pop('code')
                print(attrs)
                return attrs
            else:
                raise ValidationError('手机号不合法')
        else:
            raise ValidationError('验证码错误')

    def create(self, validated_data):
        user = models.User.objects.create_user(**validated_data)
        return user


